import { type BetterAuthOptions, betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { emailOTP, organization } from "better-auth/plugins";

import { db } from "../lib/db";
import * as schema from "../schemas/auth";
import { sendOTPVerifyEmail } from "./email";

const authConfig = {
  database: drizzleAdapter(db, {
    provider: "pg",
    schema,
  }),
  trustedOrigins: [process.env.CORS_ORIGIN || "", "http://localhost:3000"],
  socialProviders: {
    github: {
      clientId: process.env.GITHUB_CLIENT_ID as string,
      clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
    },
  },
  secret: process.env.BETTER_AUTH_SECRET,
  baseURL: process.env.BETTER_AUTH_URL,

  plugins: [
    organization(),
    emailOTP({
      async sendVerificationOTP({ email, otp, type }) {
        if (type === "sign-in") {
          await sendOTPVerifyEmail({ email, otp });
        }
      },
      expiresIn: 600,
    }),
  ],
  databaseHooks: {
    user: {
      create: {
        after: async (user) => {
          await createDefaultOrganization(user);
        },
      },
    },
    session: {
      create: {
        before: async (session) => {
          return await setActiveOrganization(session);
        },
      },
    },
  },
} satisfies BetterAuthOptions;

export const auth = betterAuth(authConfig) as ReturnType<typeof betterAuth<typeof authConfig>>;

async function createDefaultOrganization(user: typeof auth.$Infer.Session.user) {
  await auth.api.createOrganization({
    body: {
      userId: user.id,
      name: `${user.name}'s Organization`,
      slug: user.name,
    },
  });
}

async function setActiveOrganization(session: { userId: string }) {
  const firstOrg = await db.query.member.findFirst({
    where: (member, { eq }) => eq(member.userId, session.userId),
  });
  return {
    data: {
      ...session,
      activeOrganizationId: firstOrg?.organizationId,
    },
  };
}
